package compilers.types;

import java.io.BufferedWriter;
import java.io.IOException;

import compilers.table.MemScope;

public class CharType extends IntType {
	
	public CharType(char value, boolean constant) {
		super(((int)value), constant);
	}
	
	public CharType(float value, boolean constant) {
		super(value, constant);
	}

	public CharType(boolean constant) {
		super(constant);
	}

	public boolean isNumeric() {
		return false;
	}
	
	public void print(int tab) {
		for (int i=1;i<=tab;i++){System.out.print("\t");}System.out.print("|-");
		
		if (this.getfIdentifier() != null) {
			if (this.isArray()) {
				System.out.println("CharType Array [" + this.getArray() +"] (" + getfIdentifier().getfIdentifier() + ")");
			} else {
				System.out.println("CharType (" + getfIdentifier().getfIdentifier() + ")");
			}
		} else {
			if (this.isArray()) {
				System.out.println("CharType Array [" + this.getArray() +"] (" + fValue + ")");
			} else {
				System.out.println("CharType (" + ((char)fValue) + ")");
			}
		}
	}
	
	public Type computeOperation(Type second, String op) {
		// this and second of type char
		IntType tmp = new IntType(fValue, this.isConstant());
		if (second instanceof CharType) {
			CharType c = (CharType)second;
			second = new IntType(c.fValue, second.isConstant());
		}
		if (tmp.getClass().isInstance(second)) {
			return second.computeOperation(tmp, op);
		} else {
			return tmp.computeOperation(second, op);
		}
	}
	
	public Type computeFactor(String pre) {
		// Convert to int
		IntType tmp = new IntType(fValue, this.isConstant());
		return tmp.computeFactor(pre);
	}
	
	public Type newInit() {
		return new CharType(true);
	}

	public void generate(BufferedWriter writer, MemScope scope) throws IOException {	
		if (this.getfRes() == null) {
			System.out.println("throwing away useless code");
		} else {
			if (this.getfIdentifier() == null) {
				writer.write("ldc c " + ((int)fValue) + "\n");
			} else if (scope.get(getfIdentifier().getfIdentifier()) == -1) {
				// Array
				writer.write("ldc c 0\n");
			} else {
				writer.write("lod c " + scope.getDepth(getfIdentifier().getfIdentifier(), 0) + " " + scope.get(getfIdentifier().getfIdentifier()) + "\n");
			}
			
			if(getCast() != null && !getCast().getClass().equals(this.getClass())) {
				writer.write("conv c " +  getCast().getPType() + "\n");
				if (!getCast().getClass().equals(getfRes().getClass())) {
					writer.write("conv " + getCast().getPType() + " c\n");
				}
			} else if (!this.getfRes().getClass().equals(this.getClass())) {
				writer.write("conv c " + this.getfRes().getPType() + "\n");
			}
		}
	}
	
	public char getPType() {
		return 'c';
	}
}
